using System.Text;

namespace TPXSDK.NET.Mission.Instruction;

internal class InstCircleRight : Tokenizer
{
    public InstCircleRight(TokenizerAdmin admin)
    {
        Admin = admin;
        KeyName = "circleright";
        KeyValue = (int)FlyCmdId.CMD_CIRCLERIGHT;
        Usage = @"circleright [(waypoint)] [,alt]";
        Description = @"Fly a circle to the right (clockwise) around the specified waypoint";
    }

    public override bool Process()
    {
        var flyCmp = Admin?.Compiler; if (null == flyCmp) return false;
        var tokens = flyCmp.GetLineTokens();

        if (null == tokens || tokens.Count > 4)
        {
            flyCmp.ErrorMsg = $"{KeyName} Invalid Usage";
            return false;
        }
        var cmd = new FlyCmdItem
        {
            Id = (byte)KeyValue,
            LineNum = tokens[0].Row
        };

        if (1 == tokens.Count)
        {
            cmd.P1 = (byte)ParaType.EMPTY;
            cmd.P2 = 0;
            flyCmp.CmdList.Add(cmd);
            return true;
        }

        tokens.RemoveAt(0);// Remove cmd Name
        if (tokens[0].Type == TokenType.ABS_POS ||
            tokens[0].Type == TokenType.REL_POS)
        {
            if (!FlyUtils.WpToken2CmdItemP1(tokens[0], cmd))
            {
                flyCmp.ErrorMsg = $"{KeyName} Invalid center";
                return false;
            }

            if (tokens.Count == 2)
            {
                cmd.P2 = FlyUtils.ToInt16(tokens[1].Name);
            }
            flyCmp.CmdList.Add(cmd);
        }
        else if (tokens[0].Type == TokenType.NUMBER)
        {
            cmd.P1 = (byte)ParaType.EMPTY;
            cmd.P2 = tokens.Count == 1 ? FlyUtils.ToInt16(tokens[0].Name) : (short)0;
            flyCmp.CmdList.Add(cmd);
        }
        else
        {
            flyCmp.ErrorMsg = $"{KeyName} Invalid param";
            return false;
        }
        return true;
    }

    public override void Reverse(FlyCmdItem cmd, StringBuilder sb)
    {
        var src = $"{KeyName} ???";
        if (cmd.P1 == (byte)ParaType.ABS_POS ||
            cmd.P1 == (byte)ParaType.REL_POS)
        {
            var strWp = FlyUtils.ParseWpFromCmdItem(cmd);
            src = 0 == cmd.P2 ? $"{KeyName} {strWp}" : $"{KeyName} {strWp}, {cmd.P2}";
        }

        if (cmd.P1 == (byte)ParaType.EMPTY)
        {
            src = 0 == cmd.P2 ? $"{KeyName}" : $"{KeyName} {cmd.P2}";
        }

        sb.AppendLine(src);
    }
}